﻿package ca.newcommerce.youtube.fileupload 
{
	import ca.newcommerce.youtube.data.DirectUploadData;
	import ca.newcommerce.youtube.data.UploadResponseData;
	import ca.newcommerce.youtube.events.DirectUploadEvent;
	import ca.newcommerce.youtube.events.FileUploadEvent;
	import ca.newcommerce.youtube.webservice.YouTubeDataClient;
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	/**
	 * ...
	 * @author Martin Legris ( http://blog.martinlegris.com )
	 */
	
 	/**
	 * Dispatched when the uploader is ready to browse
	 * @eventType ca.newcommerce.youtube.events.FileUploadEvent.TOKEN_READY
	 */
	[Event(name="file_upload_token_ready_event", type="ca.newcommerce.youtube.events.FileUploadEvent")] 
	
	/**
	 * Dispatched when the upload succeeded
	 * @eventType ca.newcommerce.youtube.events.FileUploadEvent.UPLOAD_SUCCEEDED
	 */
	[Event(name="file_upload_succeeded_event", type="ca.newcommerce.youtube.events.FileUploadEvent")] 

	/**
	 * Dispatched when the upload failed
	 * @eventType ca.newcommerce.youtube.events.FileUploadEvent.UPLOAD_FAILED
	 */
	[Event(name="file_upload_failed_event", type="ca.newcommerce.youtube.events.FileUploadEvent")] 

	
	public class DirectUploader extends EventDispatcher
	{
		protected var _dataWs:YouTubeDataClient;
		protected var _ref:FileReference;
		protected var _data:DirectUploadData;
		protected var _requestId:Number;
		
		public function get ref():FileReference { return _ref; }
		
		public function DirectUploader() 
		{
			_dataWs = YouTubeDataClient.getInstance();
		}		
		
		public function prepareUpload(title:String, description:String, category:String, keywords:Array):Number
		{
			_dataWs.addEventListener(DirectUploadEvent.TOKEN_READY, doTokenReady);
			return _requestId = _dataWs.prepareUpload(title, description, category, keywords);
		}
		
		protected function doTokenReady(evt:DirectUploadEvent):void
		{
			trace("doTokenReady:" + _requestId +" == " + evt.requestId);
			if (evt.requestId == _requestId)
			{
				_dataWs.removeEventListener(DirectUploadEvent.TOKEN_READY, doTokenReady);
				_data = evt.data;
				
				dispatchEvent(new FileUploadEvent(FileUploadEvent.TOKEN_READY));
			}
		}
		
		public function browse():void
		{
			if (_data == null)
			{
				dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_FAILED, "", "token not ready"));
			}
			else
			{
				_ref = new FileReference();
				_ref.addEventListener(Event.SELECT, doFileSelected);			
				_ref.addEventListener(Event.CANCEL, doFileCancelled);			
				_ref.addEventListener(IOErrorEvent.IO_ERROR, doFileIoError);
				_ref.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, doFileUploaded);			
				_ref.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
				
				var types:Array = [];
				types.push(new FileFilter("Videos", "*.flv;*.wmv;*.avi;*.mpg;*.mp4;*.mpeg;*.divx;*.mov"));
				
				_ref.browse(types);
			}
		}
		
		protected function doFileCancelled(evt:Event):void
		{
			dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_FAILED, "", "file selection cancelled"));
		}
		
		protected function doSecurityError(evt:Event):void
		{
			dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_FAILED, "", "securityError:"+evt.toString()));
		}		
		
		protected function doFileIoError(evt:IOErrorEvent):void
		{
			dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_FAILED, "", "ioError:"+evt.toString()));
		}
		
		protected function doFileUploaded(evt:DataEvent):void
		{
			var xml:XML = new XML(evt.data);
			var data:UploadResponseData = UploadResponseData.fromXML(xml);
			
			if (data.status == "200")
				dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_SUCCEEDED, data.id, data.status));
			else
				dispatchEvent(new FileUploadEvent(FileUploadEvent.UPLOAD_FAILED, "", "upload failed at youtube:" + data.status));
		}
		
		protected function doFileSelected(evt:Event):void
		{
			var request:URLRequest = new URLRequest(_data.url + "?nexturl="+encodeURIComponent("http://www.newcommerce.ca/ytapi/uploadResponse.php"));
			var variables:URLVariables = new URLVariables();
			variables.token = _data.token;
			request.method = URLRequestMethod.POST;
			request.data = variables;			
			_ref.upload(request, "file");			
		}
	}
}